/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author jefoutta
 */
import java.util.*;
import java.io.*;

public class SystemCalls {

    private static Hashtable<Integer, MyBufferedReader> files_handler = new Hashtable();
    private static Integer files_handler_i = 0;
    private static ArrayList<MyBufferedReader> files = new ArrayList(0);
    private FileManager prueba = new FileManager();


    public SystemCalls(){
    }

    public String parseEcho(String s){
        if(Registries.reg_table.containsKey(s.toUpperCase()))
            return this.echo(Registries.reg_table.get(s.toUpperCase()));
        else
            return this.echo(s);
    }

    public void parseOpenFile(String s1, String s2)throws IOException{
        if(Registries.reg_table.containsKey(s2))
            Registries.reg_table.get(s2).setValue(this.openFile(s1));
    }

    public void parseCloseFile(String s1) throws IOException{
        if(Registries.reg_table.containsKey(s1))
            this.closeFile(Registries.reg_table.get(s1));
    }

    public String parseReadLine(String s1, String s2)throws IOException{
        if(Registries.reg_table.containsKey(s1) && (Registries.reg_table.containsKey(s2)))
            return this.readLine(Registries.reg_table.get(s1), Registries.reg_table.get(s2));
        return this.readLine(null, null);
    }

    public void parseFork(String s1, String s2){
        if(Registries.reg_table.containsKey(s2))
            this.fork(s1, Registries.reg_table.get(s2));
    }

    public void parseGetState(String s1, String s2, String s3){
        if(Registries.reg_table.containsKey(s1))
            Registries.reg_table.get(s2).setValue(this.getState(Registries.reg_table.get(s1), Registries.reg_table.get(s3)));
        else
            Registries.reg_table.get(s2).setValue(this.getState(Integer.parseInt(s1), Registries.reg_table.get(s3)));
    }

    public boolean parseWait(String s1){
        if(Registries.reg_table.containsKey(s1)){
            return this.Wait(Registries.reg_table.get(s1).getValue());
        }return false;
    }

    public void parseSignal(String s1){
        if(Registries.reg_table.containsKey(s1))
            this.Signal(Registries.reg_table.get(s1).getValue());
    }

    public void parseEnd(){
        this.end();
    }

    public String echo(Registry rt1){
        return ("" + Registries.reg_table.get(rt1.getName()).getValue());
    }

    public String echo(String s){
        return s;
    }

    public Integer openFile(String s)throws IOException{
        files_handler.put(files_handler_i, new MyBufferedReader(s));
        files_handler_i++;
        return (files_handler_i - 1);
    }

    public void closeFile(Registry rt1) throws IOException{
        if(files_handler.containsKey(rt1.getValue()))
            files_handler.get(Registries.reg_table.get(rt1.getName()).getValue()).closeFile();
        files_handler.remove(Registries.reg_table.get(rt1.getName()).getValue());
    }

    public String readLine(Registry rt1, Registry rt2) throws IOException{
        String s = null;
        if(files_handler.containsKey(Registries.reg_table.get(rt1.getName()).getValue())){
            s = files_handler.get(Registries.reg_table.get(rt1.getName()).getValue()).readLine();
            Registries.reg_table.get(rt2.getName()).setValue(s.length());
        }
        return s;
    }

    public Integer getState(Integer val, Registry rt1){
        return PCB.proc_id.get(val).getState();
    }

    public Integer getState(Registry rt1, Registry rt2){
        if(!(PCB.proc_id.get(Registries.reg_table.get(rt1.getName()).getValue()).getState() == 5))
            Registries.reg_table.get(rt2.getName()).setValue(0);
        else
            Registries.reg_table.get(rt2.getName()).setValue(1);
        return PCB.proc_id.get(Registries.reg_table.get(rt1.getName()).getValue()).getState();
    }
    
    public void fork(String proc, Registry rt1){
        PCB child = new PCB(Scheduling.procAct,proc);
        Registries.reg_table.get(rt1.getName()).setValue(child.id);
    }

    public boolean Wait(Integer n){
        if(Semaphore.semaphores.containsKey(n)){
            return Semaphore.semaphores.get(n).Wait();
        }
        else{
            new Semaphore(n);
            return Semaphore.semaphores.get(n).Wait();
        }
    }

    public void Signal(Integer n){
        if(Semaphore.semaphores.containsKey(n))
            Semaphore.semaphores.get(n).Signal();
    }

    public void end(){
        PCB.proc_id.get(Scheduling.procAct).setState(5);
    }
}